home *** CD-ROM | disk | FTP | other *** search
/ Tech Arsenal 1 / Tech Arsenal (Arsenal Computer).ISO / tek-01 / wtek0693.zip / ECKEL.ZIP / MULTIMED.CPP < prev    next >
C/C++ Source or Header  |  1992-07-15  |  5KB  |  197 lines

  1. //: MULTIMED.CPP -- MultiMedia class implementation.
  2. //. This uses the high-level MCI string interface, but
  3. //. can be changed to use lower-level interfaces without
  4. //. changing the rest of the code in the project.
  5. #include <stdlib.h>
  6. #include <string.h>
  7. #include <strstream.h>
  8. #include <windows.h>
  9. #include "multimed.h"
  10. #include <mmsystem.h>
  11.  
  12. CD cd;  // single global instance
  13.  
  14. // Error checking MCI interface function:
  15. static char* mci_command(char* cmd) {
  16.   const size = 200;
  17.   static char returnbuf[size];  // for mci return message
  18.   int error = mciSendString(cmd, returnbuf, size, NULL);
  19.   // Return string is in returnbuf.
  20.   if(error) {
  21.     MessageBox(NULL, cmd, "MCI command causing error", MB_OK);
  22.     char errbuf[size];
  23.     if(mciGetErrorString(error, errbuf, size))
  24.     MessageBox(NULL, errbuf, "MCI error", MB_OK);
  25.     else
  26.     MessageBox(NULL, "Unknown error", "MCI error", MB_OK);
  27.   }
  28.   return returnbuf;
  29. }
  30.  
  31. int CD::open() {
  32.   if(!cd_open) {
  33.     char * isthere = mci_command("capability cdaudio can play");
  34.     if(strcmp("true", isthere) == 0) present = 1;  // disk available
  35.     if(!present) return 0;
  36.     mci_command("open cdaudio shareable");
  37.     mci_command("set cdaudio time format tmsf");
  38.     maxtracks = atoi(mci_command("status cdaudio number of tracks"));
  39.     length = new songlength[maxtracks];
  40.     for(int i = 1; i <= maxtracks; i++) {
  41.     ostrstream commandstr(command, sz);
  42.     commandstr << "status cdaudio length track " << i << '\0';
  43.     length[i-1].minutes = atoi(strtok(mci_command(command), ":"));
  44.     length[i-1].seconds = atoi(strtok(NULL, ":"));
  45.     }
  46.     cd_open = 1;
  47.   }
  48.   return 1;
  49. }
  50.  
  51. void CD::play() {
  52.   open();
  53.   if(!present) return;
  54.   state = normal;
  55.   ostrstream commandstr(command, sz);
  56.   // Note format: track:minutes:seconds:frames
  57.   commandstr << "play cdaudio from " <<
  58.     track << ":" << minute << ":"<<
  59.     second << ":00" << '\0';
  60.   mci_command(command);
  61. }
  62.  
  63. CD::CD(when w) : state(normal), cd_open(0), maxtracks(0),
  64.      length(0), track(1), minute(0), second(0), present(0) {
  65.   if(w == open_now) open();
  66. }
  67.  
  68. CD::~CD() {
  69.   if(cd_open) mci_command("close cdaudio");
  70.   delete []length; // dynamically allocated buffer
  71. }
  72.  
  73. void CD::stop() {
  74.   if(!cd_open) open();
  75.   if(!present) return;
  76.   mci_command("stop cdaudio");
  77.   track = 1; minute = second = 0;
  78.   state = normal;
  79. }
  80.  
  81. void CD::forward_track() {
  82.   if(++track > maxtracks) track = maxtracks;
  83.   minute = second = 0;
  84.   play();
  85. }
  86.  
  87. void CD::backward_track() {
  88.   if(--track < 1) track = 1;
  89.   minute = second = 0;
  90.   play();
  91. }
  92.  
  93. void CD::update_position() {
  94.   // Change internal data to reflect current CD position
  95.   if(!present) return;
  96.   track = atoi(strtok(mci_command("status cdaudio position"), ":"));
  97.   minute = atoi(strtok(NULL, ":"));
  98.   second = atoi(strtok(NULL, ":"));
  99. }
  100.  
  101. void CD::rewind() {
  102.   // Rewind:
  103.   open();
  104.   if(!present) return;
  105.   update_position();
  106.   state = frewind;
  107. }
  108.  
  109. void CD::rewind_step() {
  110.   if(--second < 0) {
  111.     if(--minute < 0) {
  112.       if(--track < 1)  {
  113.     track = 1;
  114.     minute = second = 0;
  115.       } else {
  116.     minute = length[track - 1].minutes;
  117.     second = length[track - 1].seconds;
  118.       }
  119.     } else {
  120.       second = 59;
  121.     }
  122.   }
  123. }
  124.  
  125. void CD::fast_forward() {
  126.   // Fast-forward:
  127.   open();
  128.   if(!present) return;
  129.   update_position();
  130.   state = fforward;
  131. }
  132.  
  133. void CD::fforward_step() {
  134.   if(minute == length[track-1].minutes) {
  135.     if(++second >= length[track-1].seconds)
  136.       if(++track > maxtracks) {
  137.     track = maxtracks;
  138.     minute = length[track-1].minutes;
  139.     second = length[track-1].seconds;
  140.       } else {
  141.     minute = second = 0;
  142.       }
  143.     return;
  144.   }
  145.   // Here, we aren't at the track's minute length
  146.   if(++second >= 60) {
  147.     minute++;
  148.     second = 0;
  149.   }
  150. }
  151.  
  152. ////////// SoundPlayer Method Implementations ////////////
  153.  
  154. void SoundPlayer::play(char * file) {
  155.   sndPlaySound(file, SND_ASYNC);
  156. }
  157.  
  158. SoundRecorder::SoundRecorder() : audio_used(0), recording(0) {
  159.   // You must have the empty sound file tmp.wav
  160.   // in the current directory
  161.   mci_command("open tmp.wav type waveaudio");
  162.   mci_command("cue tmp.wav input");
  163.   mci_command("delete tmp.wav from 0");
  164. }
  165.  
  166. SoundRecorder::~SoundRecorder() {
  167.   stop_recording();
  168.   mci_command("close tmp.wav");
  169. }
  170.  
  171. void SoundRecorder::start_recording() {
  172.   char *ready = mci_command("status tmp.wav ready");
  173.   if(strcmp(ready, "true") != 0) {
  174.     MessageBox(NULL, ready, "tmp.wav not ready", MB_OK);
  175.     return;
  176.   }
  177.   if(audio_used) {
  178.       mci_command("delete tmp.wav from 0");
  179.   }
  180.   mci_command("record tmp.wav from 0");
  181.   audio_used = recording = 1;
  182. }
  183.  
  184. void SoundRecorder::stop_recording() {
  185.   if(recording) {
  186.     mci_command("stop tmp.wav");
  187.     recording = 0;
  188.   }
  189. }
  190.  
  191. void SoundRecorder::save(char * file) {
  192.   stop_recording();
  193.   ostrstream commandstr(command, sz);
  194.   commandstr << "save tmp.wav " << file << '\0';
  195.   mci_command(command);
  196. }
  197.